import csv
from typing_extensions import OrderedDict

from backend.eform.utils import checkCanDelete, checkCanEndorse, checkCanVerify, getClientIP, resetEformCheckState
from backend.eform.hierarchy_checksheet import HierarchyChecksheet
from django.shortcuts import redirect, render
from django.urls import reverse
from rest_framework import status
from django.http import Http404, JsonResponse, StreamingHttpResponse

from backend.eformConvert.models import EformSQL
from .models import *
import datetime
import json
import backend.eform.builder_fields as bf
from django.conf import settings
from backend.eform.forms import copySchemaForm, importCSVForm
from .signals import eform_done_signal,eform_save_signal,eform_endorse_signal,eform_verify_signal
from .utils import getEformSchema, lockEform
from django.db.models.deletion import ProtectedError
from django.utils import timezone
from backend.schema.eform_schema import EformWorkOrderSchema
## logger
from logger.createlogger import create_logger

## CEWS
from backend.cews.models import RepairOrderTask

logger = create_logger('eform_views')

_HC = HierarchyChecksheet()
if _HC.hc_dict=={}:
    _HC.hc_dict = _HC.loadFromCsv()
    # _HC.saveAsJson()

def eformRoutingView(request,workorder_pk):
    """
        redirect user to 
        1. choese new form for workoredere
        2. existing form for the workorder
        3. for verifer or endorser to check the form
    """
    ##
    context = {}
    # wo = WorkOrderList.objects.filter(pk=workorder_pk).select_related('brokenpart').first()
    ## FIXME:
    wo= False
    # wo not found return to last page
    # next = request.GET.get('next',False)
    if not wo:
        # if not next:
        #     raise Http404()
        # return redirect(next)
        raise Http404()


    # type = request.GET.get('type')
    # next = request.GET.get('next')

    ## TODO: found the form base on the hirecy 
    # concatch hc key
    # device = DeviceList.objects.filter(id=wo.brokenpart_id).first()
    
    # eform = Eform.objects.filter(workOrderList_pk=wo.pk).first()

    eform = Eform.objects.filter(workOrderList_pk=wo.pk).first()
    if eform:
        ## redirect user to existing form
        ## now user can verify themself
        if eform.doneDate:
            return redirect(reverse('eform:checkEform',kwargs={'pk':eform.pk}))
        
        # if request.user.id == eform.doneby_id:
        return redirect(reverse('eform:eformView',kwargs={'pk':eform.pk}))


    ## filter eform by hkey
    # hkey = wo.brokenpart.HKey
    hkey = ''
    ##  render eform list page for user select a correct form  
    cs = False
    if hkey:
        cs = _HC.findChecksheets(hkey)
    if cs:
        es = EformSchema.objects.all().filter(formNo__in=cs).order_by('formNo')
        if not es:
            es = EformSchema.objects.all().order_by('formNo')    
    else:
        es = EformSchema.objects.all().order_by('formNo')

    eforms = [e for e in es if e.enable]

    context['workOrder_id'] = workorder_pk
    context['eforms'] = eforms
    context['wo'] = wo
    return render(request,'chooseForm.html',context)

def eformSchemaView(request,pk):
    context={}
    es = EformSchema.objects.get(pk=pk)
    if not es:
        raise Http404()

    efs = Eform.objects.filter(eformSchema=es)
    context['eforms'] = efs
    context['es'] = es
    
    return render(request,'eformSchemaView.html',context)


def checkEformView(request,pk): ## form view for verify and endorse
    
    ## get eform
    eform = Eform.objects.get(pk=pk)
    message = False
    check_require = False
    check_type = 'None'## verify  or endorsor
    color= 'success'
    check_string = '' ## use to display current checkstate text on UI
    eformFile = EformFile.objects.filter(eform=eform)

    # 改写了tester只执行一个done
    role = request.GET.get("role", None)
    if role == RepairOrderTask.RoleType.TESTER:
        endorse_required = False
    else:
        endorse_required = eform.eformSchema.endorsor_require

    if request.POST and endorse_required:
        ## determine verify or endorsor 
        action = request.POST.get('action',False)
        
        # type = request.POST.get('type')
        # next = request.GET.get('next')
        
        ## handle check as other user
        user_id = request.POST.get('user_id',False)
        
        is_check_as_other = user_id != False and user_id != '-1'
        
        selected_user = request.user
        if is_check_as_other:
            user = User.objects.get(pk=user_id)
            if user:
                selected_user = user

        ## TODO: support enter password
        # ## check is username and password selected 
        # username = request.POST.get('username',False)
        # password = request.POST.get('password',False)
        
        # if username and password:
        #     myuser = authenticate(username=username,password=password)
        #     if myuser:
        #         selected_user = myuser
        #     else:
        #         message = "Username or Password incorrect."
        #         color='warning' 
        flow = request.GET.get("flow", None)
                
        overall_test_result = request.POST.get('overall_test_result_radio', False)
        endorsment_result  = request.POST.get('endorsment_result_radio',False)
        verify_sic_resulta = request.POST.get('verify_sic_resulta_radio',False)

        if overall_test_result:
            eform.overall_test_result = overall_test_result

        if endorsment_result:
            eform.endorsment_result = endorsment_result
        
        if verify_sic_resulta:
            eform.verify_sic_resulta = verify_sic_resulta

        check_user_per = True
        if flow == RepairOrderTask.FlowType.ENDORSE:
            check_user_per = eform.check_user_endorse_permissions(selected_user.id)
            if not endorsment_result:
                action = None
                message="endorsment_result必填"
                color='warning'

        elif flow == RepairOrderTask.FlowType.VERIFY:
            check_user_per = eform.check_user_verified_permissions(selected_user.id)
            if not verify_sic_resulta:
                action = None
                message="verify_sic_resulta必填"
                color='warning'

        elif flow == RepairOrderTask.FlowType.DONE:
            if not overall_test_result:
                action = None
                message="Verify user duplicated必填"
                color='warning'

        logger.debug(action)
        if action:
            if action =='verify':
                if checkCanVerify(selected_user):
                    ## check user cannot be dupilcated
                    if not eform.checkUserDuplication(selected_user.id):
                        if check_user_per:

                            eform.verifiedby_id = selected_user.id
                            eform.verifiedDate = datetime.datetime.now()

                            ## depreciated, if the form endorsor_require == False, no verify and endorse needed
                            # if eform.eformSchema.endorsor_require == False:
                            #     ## if not require to endros, auto endorse
                            #     eform.endorsedby_id = selected_user.id
                            #     eform.endorsedDate = datetime.datetime.now()

                            message ="Verified."
                            eform_verify_signal.send(sender=None,instance=eform)

                        else:
                            message = "You do not have verify permission, plesase check it"
                            color='warning'
                        # send email
                    else:
                        message="Verify user duplicated."
                        color='warning'
                else:
                    message = "Verify Fail, Insufficient Permission."
                    color="warning"

            elif action =='endorse':
                # print(eform.workOrderList.next_step.stationName== 'FINAL INSPECTION')
                if checkCanEndorse(selected_user):
                    ## check user cannot be dupilcated
                    if not eform.checkUserDuplication(selected_user.id):
                        if check_user_per:
                            # if eform.workOrderList.next_step.stationName == 'FINAL INSPECTION':
                            eform.endorsedby_id = selected_user.id
                            eform.endorsedDate = datetime.datetime.now()
                            
                            message = "Endorsed."
                            eform_endorse_signal.send(sender=None,instance=eform)
                            # send email

                            # else:
                            #     message = "You can ENDORSE the form ONLY when work order in FINAL INSPECTION stage"
                            #     color='warning'
                        else:
                            message = "You do not have endorsement permission, plesase check it"
                            color='warning'
                    else:
                        message="Endorse user duplicated."
                        color='warning'
                else:
                    message = "Endorse Fail, Insufficient Permission."
                    color="warning"

            elif action =='delete':
                if checkCanDelete(request.user):
                    if check_user_per:
                        return deleteEform(eform)
                    else:
                        message = "You do not have deleted permission, plesase check it"
                        color="warning"
                else:
                    message="Delete Fail, Insufficient Permission."
                    color="warning"

            elif action =='reset':
                if checkCanVerify(request.user) or checkCanEndorse:
                    if check_user_per:
                        resetEformCheckState(eform)
                        eform_done_signal.send(sender=None,instance=eform)
                        # print('reset form')
                        return redirect(reverse("eform:eformView",kwargs={'pk':eform.id}))
                    else:
                        message = "You do not have reset permission, plesase check it"
                        color='warning'
                else:
                    message="Reset Approval State Fail, Insufficient Permission."
                    color='warning'
            else:
                message= "Saved"


            ## update eform
##            if eform.workOrderList:
 ##               updateWorkOrderFields(eform.workOrderList,request)
            eform.save()
        # pass

    # print(eform.eformSchema.endorsor_require)
    # print(not eform.endorsedby)

    if endorse_required:
        if not eform.verifiedby:
            check_require = True
            check_type = 'verify'
            check_string = 'Verify'

        elif  eform.eformSchema.endorsor_require and not eform.endorsedby:
            check_require = True
            check_type = 'endorse'
            check_string = 'Endorse'

    # wo_imte = WorkOrderList_Imte.objects.filter(workOrderList=eform.workOrderList)/
    # FIXME
    wo_imte = []

    # 改写了tester只执行一个done
    if role == RepairOrderTask.RoleType.TESTER:
        endorse_required = eform.eformSchema.endorsor_require = False
    context={
        'eform':eform,
        'eformFile':eformFile,
        'formSchema': getEformSchema(eform),
        'check_require':check_require,
        'check_type':check_type,
        'check_string':check_string,
        'message': message,
        'color':color,
        'imtes': wo_imte
    }
    
    return render(request,'checkEform.html',context)

def listView(request):
    eformTemplates = EformSchema.objects.all()
    context = {
        'eforms':eformTemplates,
        'new':int(request.GET.get('new',False))
    }
    return render(request,'list.html',context)

def eformPrintView(request,pk):
    ## get eform
    eform = Eform.objects.get(pk=pk)
    if not eform:
        raise Http404()
    csv_msg=""
    ##FIXME
    # wo_imte = WorkOrderList_Imte.objects.filter(workOrderList=eform.workOrderList)
    wo_imte = []
    eformFile = EformFile.objects.filter(eform=eform)
    context={
        'eform':eform,
        ## use formSchema instead of extFormSchema
        'formSchema': getEformSchema(eform),
        'imtes': wo_imte,
        'eformFile':eformFile
    }
    return render(request,'eformPrintView.html',context)

def eformView(request,pk): ## form view
    csv_msg=False
    ## get eform
    message = False
    color = 'success'
    print(request)
    eform = Eform.objects.get(pk=pk)
    if not eform:
        raise Http404()
    
    ## get order 
    rot = RepairOrderTask.objects.get(eform_id=pk,eform_schema_id=eform.eformSchema.id)
    if request.POST:

        ## TODO: handle delete
        action = request.POST.get('action')

        received_date = ""
        if rot.repair_order.check_in:
            received_date = rot.repair_order.check_in.strftime("%Y-%m-%d")
        eform_work_schema = EformWorkOrderSchema(
                checked_date=datetime.datetime.now().strftime("%Y-%m-%d"),
                failure_sym=request.POST['wo_failure_sym'],
                location=request.POST['wo_location'],
                action=request.POST['wo_action'],
                finding=request.POST['wo_finding'],
                serialno=rot.serial_no,
                line_order=request.POST['wo_line_w_order'],
                cews_order=request.POST['wo_cews_w_order'],
                received_date=received_date, # 这个地方是需要取pg还是，存到mongo
            )
        if action == 'done':
            eform.doneby_id = request.user.id

            updateEform(request,eform, eform_work_schema) 
            progress = eform.getProgress
            
            if (isinstance(progress,(float,int)) and progress >= 100):
                eform.doneDate = datetime.datetime.now()
                message="Form Done"
            else:
                message = "Progress not 100%, please fill all required fields."
                color="warning"
            if isinstance(progress,(bool)) and progress == False:
                eform.doneDate = datetime.datetime.now()
                message="Form Done"
                color="success"

            ## if the eform's schema_lock is not locked
            ## lock eform 
            if eform.schema_lock == False:
                ret = lockEform(eform)
                if not ret:
                    logger.critical("Cannot lock eform during done action")
                    
            eform_done_signal.send(sender=None,instance=eform)
            
            eform.save()

        if action == 'save':
            updateEform(request,eform, eform_work_schema)  
            eform_save_signal.send(sender=None,instance=eform)
            message="Saved"

        if action=='delete':
            return deleteEform(eform)
            # wo_pk = eform.workOrderList.pk
            # eform.workOrderList = None
            # eform.save()
            # return redirect(reverse('eform:eformRoutingView',kwargs={'workorder_pk':wo_pk}))

        if "importform" in request.POST:
            importform = importCSVForm(request.POST, request.FILES)
            if importform.is_valid():
                csv_msg = importform.uploadData(eform)

    ## FIXME
    # wo_imte = WorkOrderList_Imte.objects.filter(workOrderList=eform.workOrderList,due_date__gt=datetime.datetime.now())
    wo_imte = []
    # is_psu = wo_imte.filter(imte_type__in=("P","p")).count() >0
    # is_meter = wo_imte.filter(imte_type__in=("M","m")).count()>0
    is_psu = False
    is_meter = False
    # eform file
    eformFile = EformFile.objects.filter(eform=eform)
    
    # FIXME
    # locations = LocationList.objects.all()
    locations = []
    ## get paired ip
    # clientIp = getClientIP(request)
    ODI = False
    # if clientIp:
    pm = False
    # pm = PairUpModel.objects.filter(tab_user = request.user).first()
    if pm:
        ODI = pm.tableip

    formSchema = getEformSchema(eform)

    locations.append(rot.repair_order.location)
    importform = importCSVForm()
    role = request.GET.get("role", None)
    if role == RepairOrderTask.RoleType.TESTER:
        eform.eformSchema.endorsor_require = False


    context={
        'eform':eform,
        'formSchema': formSchema,
        'OCR_DETECTION_IP': ODI,
        'message':message,
        'color':color,
        'imtes': wo_imte,
        'eformFile':eformFile,
        'is_psu': is_psu,
        'is_meter':is_meter,
        'locations':locations,
        'importform':importform,
        'csv_msg':csv_msg,
        'serial_no':rot.serial_no,
        'failure_sym':rot.repair_order.failure_symptom,
        'equipment':rot.repair_order.eqpt_description,
        'received_date':rot.repair_order.check_in.strftime("%Y-%m-%d"),
        'line_order':rot.repair_order.line_work_order,
        'cews_order':rot.repair_order.work_order_no,
    }
    if eform.workOrder:
        if re_date := eform.workOrder['received_date']:
            context["received_date"] = re_date
        if line_order := eform.workOrder['line_order']:
            context["line_order"] = line_order
        if failure_sym := eform.workOrder['failure_sym']:
            context["failure_sym"] = failure_sym
        if cews_order := eform.workOrder['cews_order']:
            context["cews_order"] = cews_order
            
    return render(request,'eformView.html',context)

def eformDisableView(request,pk): ## form view
    eform = Eform.objects.get(pk=pk)
    if not eform:
        raise Http404()
    csv_msg=""
    ##FIXME
    # wo_imte = WorkOrderList_Imte.objects.filter(workOrderList=eform.workOrderList)
    wo_imte = []
    eformFile = EformFile.objects.filter(eform=eform)
    context={
        'eform':eform,
        ## use formSchema instead of extFormSchema
        'formSchema': getEformSchema(eform),
        'imtes': wo_imte,
        'eformFile':eformFile
    }
    return render(request,'eformDisableView.html',context)

def newEformView(request):
    """
        create a new eform with eformSchema_id 
        @param workOrderList_pk: String of workorder, used to query information 
    """
    context = {}
    
    eformSchema_id = request.POST.get('eformSchema_id',False)

    ## FIXME:
    # workOrder = WorkOrderList.objects.get(pk=workOrderList_pk)
    # workOrder = False    
    
    eform = createEform(request,eformSchema_id)
    # # eform.eform_in_or_out=type
    eform.save()
    
    if not eform:
        print('eform not found')
        raise Http404()

    
    return redirect(reverse('eform:eformView',kwargs={'pk':eform.id}))

def schemaBuilderEditView(request,pk):
    # if request.POST:
    #     postFormTemplate(request)
    context = {}
    context['components'] = json.dumps(bf.getComponents())
    eformSchema = EformSchema.objects.get(id=pk)
    if not eformSchema:
        return Http404()
    
    if (updateFormTemplate(request,eformSchema)):
        eformSchema = EformSchema.objects.get(id=pk)
    else:
        context['message'] = 'Cannot Save Form Schema Please Try Again'
    
    context['eform']=eformSchema
    
    return render(request,'builder_edit.html',context)

def schemaBuilderNewView(request):
    context = {}
    context['components'] = json.dumps(bf.getComponents())
    if request.POST:
        newEform = postFormTemplate(request)
        # print(newEform)
        return redirect(reverse('eform:list')+f'?new={newEform.id}')
    # eform = EformSchema.objects.filter(_id=pk)v
    # print(eform.pk)

    return render(request,'builder_new.html',context)


def updateFormTemplate(request,eformSchema):
    schemaJson = request.POST.get('dataJson',False)
    ## Meta data
    form_title = request.POST.get('form_title',False)
    form_no = request.POST.get('form_no',False)
    ref = request.POST.get('ref',False)
    enable = request.POST.get('enable',False)
    endorsor_require = request.POST.get('endorsor_require',False)
    form_issue_date = request.POST.get('form_issue_date',False)
    issue = request.POST.get('issue',False)
    if schemaJson:
        if form_title:
            eformSchema.title = form_title
        if form_no:
            eformSchema.formNo = form_no
        if ref:
            eformSchema.ref = ref
        if endorsor_require:
            eformSchema.endorsor_require = endorsor_require == 'Yes'
        if enable:
            eformSchema.enable = enable == 'Yes'
        if issue or issue=="": 
            eformSchema.issue=issue
        if form_issue_date or form_issue_date=="":
            if form_issue_date=="":
                eformSchema.form_issue_date = None
            else:
                eformSchema.form_issue_date = form_issue_date
            
        eformSchema.formSchema = json.loads(schemaJson)
        eformSchema.updated = datetime.datetime.now()
        eformSchema.save()

        return True
    else:
        return False


def postFormTemplate(request):
    # checkUserValid(request)
    ## Check permission
    print(request.POST)
    
    schemaJson = request.POST.get('dataJson',False)
    form_title = request.POST.get('form_title',False)
    form_no = request.POST.get('form_no',False)
    ref = request.POST.get('ref',False)
    endorsor_require = request.POST.get('endorsor_require',False)
    form_issue_date = request.POST.get('form_issue_date',False)
    issue = request.POST.get('issue',False)
    if schemaJson:
        formSchema = json.loads(schemaJson)
        eformSchema = EformSchema(
            title=form_title,
            formNo=form_no,
            ref = ref,
            endorsor_require=endorsor_require == 'Yes',
            formSchema=formSchema,
        )
        
        if issue:
            eformSchema.issue= issue

        if form_issue_date:
            if form_issue_date=="":
                eformSchema.form_issue_date = None
            else:
                eformSchema.form_issue_date = form_issue_date
    
        eformSchema.save()
        print(eformSchema.form_issue_date)
        # print(schemaJson)
        # print(eformSchema._id)
        return eformSchema
    else:
        return False
        

def createEform(request,eformSchema_id):
    """
        create eform with 
        @param {string,int} eformSchema_id
        @param {WorkOrderList} workOrder
    """
    eform  = Eform()
    eformSchema = EformSchema.objects.get(pk=eformSchema_id)
    eform.eformSchema = eformSchema
    eform.extFormSchema = eformSchema.formSchema
    eform.doneby_id = request.user.id
    # eform.workOrderList_pk = workOrder.pk
    eform.save()
    return eform

def updateWorkOrderFields(wo,request):
    """
        @params {WorkOrderList} wo
        @params {HttpRequest} request
        update wo failure symptom, finding, action and remarks
    """
    print(request.POST)
    failure_sym = request.POST.get('wo_failure_sym',False)
    finding = request.POST.get('wo_finding',False)
    action = request.POST.get('wo_action',False)
    remarks = request.POST.get('wo_remarks',False)

    failure_sym = request.POST.get('wo_failure_sym',False)
    location = request.POST.get('wo_location',False)
    received_date = request.POST.get('wo_received_date',False)
    line_w_order = request.POST.get('wo_line_w_order',False)
    checkout_date = request.POST.get('wo_checkout_date',False)

    cews_w_order = request.POST.get('wo_cews_w_order',False)

    if failure_sym:
        wo.failure_sym = failure_sym
    if finding:
        wo.finding = finding
    if action:
        wo.action = action
    if remarks:
        wo.remarks = remarks
    if location:
        # FIXME
        # loc = LocationList.objects.filter(id=location).first()
        loc = False
        if loc:
            wo.location = loc
    else:
        wo.location = None

    
    if received_date:
        wo.received_date = received_date
    if line_w_order:
        wo.line_w_order = line_w_order
    if checkout_date:
        wo.checkout_date = checkout_date
    
    if cews_w_order:
        wo.cews_w_order=cews_w_order

    wo.save()


def updateEform(request,eform:Eform, work_order: EformWorkOrderSchema):
    """
        serialize dataJson to Array of FormData  and store to the eform
        @param: eform 
    """
    dataJson = request.POST.get('dataJson',False)
    test_result = request.POST.get('overall_test_result',False)
    if not dataJson:
        return False
    
    data = json.loads(dataJson)
    if test_result:
        eform.overall_test_result = test_result

    eform.extform_issue_date = timezone.now()
    eform.formData = data
    eform.workOrder = work_order.model_dump()
    eform.save()

    # print(eform.workOrderList)
    
    # if eform.workOrderList:
    #     updateWorkOrderFields(eform.workOrderList,request)
    ## TODO: put edit log

    return eform
    
    
# def deleteEform(eform, type, next):
def deleteEform(eform):
    # wo_pk = eform.workOrderList_pk
    # eform.workOrderList_pk = None
    eform.delete()
    
    EFORM_DELETE_REDIRECT_URL =getattr(settings,'EFORM_DELETE_REDIRECT_URL','')
    
    return redirect(EFORM_DELETE_REDIRECT_URL)


def schemaBuilderCopyView(request):
    context = {}
    copyschemaform=copySchemaForm()
    context['copyschemaform'] = copyschemaform
    if request.method=="POST" and "copyschemaform" in request.POST:
        copyschemaform = copySchemaForm(request.POST)
        pk = request.POST.get('formNo', None)
        if pk:
            es = EformSchema.objects.get(pk=pk)
            es.pk = None
            es.save()
            return redirect(reverse('eform:schemaBuilder',kwargs={'pk':es.pk}))
    return render(request,'copyschema.html',context)

def deleteSchemaBuilder(request, pk):
    context = {}
    print("request.method", request.method)
    eformSchema = EformSchema.objects.get(id=pk)
    if request.method=="POST":
        try:
            eformSchema.delete()
            return redirect(reverse('eform:list'))
        except ProtectedError as e:
            err_msg="This schema is used by other eform. It is not allowed to delete."
            context['err_msg'] = err_msg

    context['es'] = eformSchema
    return render(request,'deleteschema.html',context)


def eformConvertView(request):
    context = {}
    # eform = Eform.objects.all().filter(converted_date=None)
    eform = Eform.objects.all()
    qs_option = request.GET.get('s',False)

    if qs_option==False or qs_option == "n":
        eform = eform.filter(converted_date=None)

    if qs_option == "d":
        eform = eform.filter(doneDate__isnull= False)

    if qs_option == "c":
        eform = eform.filter(converted_date__isnull=False)
        
    context['eform'] = eform
    
    return render(request,'eformConvert.html',context)
    

def eformConvertAPI(request):
    eform_id = request.POST.get('eform_id',False)
    overwrite = request.POST.get('overwrite',False)

    if overwrite:
        overwrite = True if overwrite=="true" else False
    
    eform = Eform.objects.filter(id = eform_id).first()
    
    

    if not request.user.has_perm('eform.can_convert_eform'):
        print(request.user.get_user_permissions())
        return JsonResponse(status=status.HTTP_403_FORBIDDEN,
        data={
            'message':'No permission',
            # 'perms':request.user.get_user_permissions()
        })
   
    if not eform:
        return JsonResponse(status=status.HTTP_404_NOT_FOUND,data={
            'message':"Eform not found"
        })
    
    wo = eform.workOrderList
    
    if not wo:
        return JsonResponse(status=status.HTTP_404_NOT_FOUND,
            data={
                'message':'WorkOrder not found'
            }
        )

    if overwrite:
        esql = EformSQL.objects.filter(form_id=eform_id)
        esql.delete()


    ## get form info
    es = eform.eformSchema
    form_title = es.title
    form_id = eform.id

    ## insert wo fields 
    # form_element_id
    # form_element_title
    # form_element_type
    # value
    # eformSQL = EformSQL(
    #     form_element_id = ,
    #     form_element_title = ,
    #     form_element_type = ,
    #     value = ,
    # )

    toCreate = []
    toCreate.append(
        EformSQL(
            form_title = es.title,
            form_id = eform.id,
            form_element_id = 'id_wo_failure_sym',
            form_element_title = 'failure_sym',
            form_element_type ='text' ,
            value = wo.failure_sym ,
        )
    )

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_finding',
        form_element_title = 'finding',
        form_element_type ='text' ,
        value = wo.finding ,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_action',
        form_element_title = 'action',
        form_element_type ='text' ,
        value = wo.action ,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_remarks',
        form_element_title = 'remarks',
        form_element_type ='text' ,
        value = wo.remarks ,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_location',
        form_element_title = 'location',
        form_element_type ='text' ,
        value = wo.location ,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_received_date',
        form_element_title = 'received_date',
        form_element_type ='date' ,
        value = wo.received_date ,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_line_w_order',
        form_element_title = 'line_w_order',
        form_element_type ='text' ,
        value = wo.line_w_order ,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_cews_w_order',
        form_element_title = 'cews_w_order',
        form_element_type ='text',
        value = wo.cews_w_order,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_checkout_date',
        form_element_title = 'checkout_date',
        form_element_type ='date' ,
        value = wo.checkout_date ,
    ))

    toCreate.append(EformSQL(
        form_title = es.title,
        form_id = eform.id,
        form_element_id = 'id_wo_fault_action',
        form_element_title = 'fault_action',
        form_element_type ='text' ,
        value = wo.fault_action ,
    ))

    ## eform .data
    formData = eform.formData

    for key,v in formData.items():
        ele = formData[key]  
        value = ""  
        dataType = "text"
        value_number = None
        
        if isinstance(ele,OrderedDict):
            ## is checkboxes 
            temp =[]
            for vkey,v in ele.items():
                is_selected = ele[vkey]
                if is_selected:
                    temp.append(vkey)
            if len(temp)>0:
                value = ','.join(temp)
        else:
            if ele:
                value = ele
            ## check type
            if isinstance(ele,int):
                dataType="int"
                if value != None and value != '':
                    value_number = value
            if isinstance(ele,float):
                dataType="float"
                if value != None and value != '':
                    value_number = value
            if isinstance(ele,datetime.date):
                dataType ="date"
        print(f"value_number:{value_number}")
        if value is None:
            value= ""
            
        toCreate.append(EformSQL(
            form_title = es.title,
            form_id = eform.id,
            form_element_id = f"id_{key}",
            form_element_title = key,
            form_element_type =dataType ,
            value = value ,
            value_number = value_number
        ))

    # print(toCreate)
    try:
        EformSQL.objects.bulk_create(toCreate)
        eform.converted_date = datetime.datetime.now()
        eform.save()
        message = f"EForm_id {eform.id}: converted."
        if overwrite:
            message = f"EForm_id {eform.id}: converted and overwrited."
        return JsonResponse(status=status.HTTP_201_CREATED,data={
            'message': message
        })
    except Exception as ex:
        
        return JsonResponse(status=status.HTTP_500_INTERNAL_SERVER_ERROR,
            data={
                'message':str(ex)
            }
        )


class Echo:
    def write(self,v):
        return v

def eformsql_stream_csv(request):
    
    if not request.user.has_perm('eform.can_convert_eform'):
        return JsonResponse(status=status.HTTP_403_FORBIDDEN,data={
            'message':'No permission'
        })
    data = EformSQL.objects.all().order_by('-id')
    rows =[
        [d.form_id,d.form_title,d.form_element_id,d.form_element_title,d.form_element_type,d.value,d.created]
        for d in data
    ]
    pb = Echo()
    writer = csv.writer(pb)
    now =datetime.datetime.now().strftime("%Y_%m_%d_%H_%M_%S")
    filename=f"eform_csv_{now}.csv"
    return StreamingHttpResponse(
        (writer.writerow(row) for row in rows),
        content_type="text/csv",
        headers={'Content-Disposition': f'attachment; filename="{filename}"'},
    )   

def eformPreviewView(request,schema_id):  
    schema = EformSchema.objects.filter(id=schema_id).first()
    if not schema:
        return Http404()

    context = {
        "formSchema":json.dumps(schema.formSchema),
        "eform":{
            "eformSchema":schema
        }
    }

    return render(request,'eformPreview.html',context)